package com.jungle.client;


import com.google.gson.reflect.TypeToken;
import com.jungle.bfi.domain.vo.DatasetItemVo;
import com.jungle.bfi.domain.vo.DatasetVo;
import com.jungle.client.channel.HttpClient;
import com.jungle.client.utils.TableViewUtil;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.TableView;
import javafx.scene.input.MouseEvent;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.ResourceBundle;

@Slf4j
public class DatasetController implements Initializable {
    @FXML
    private Button editDataset;
    @FXML
    private Button deleteDataset;
    @FXML
    private TableView<DatasetVo> tableView;

    @FXML
    private Button addDatasetItem;
    @FXML
    private Button deleteDatasetItem;
    @FXML
    private Button editDatasetItem;
    @FXML
    private TableView<DatasetItemVo> datasetItem;

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        log.info("init DataSetController, location:{}", location);

        initDataset();
        loadDataset();

        initDataSetItem();
    }

    private void initDataset() {
        // 监听选中行
        tableView.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
            boolean disable = newValue == null;
            editDataset.setDisable(disable);
            deleteDataset.setDisable(disable);
            if (disable) {
                datasetItem.getItems().clear();
                addDatasetItem.setDisable(true);
            } else {
                loadDatasetItem(newValue.getId());
                addDatasetItem.setDisable(false);
            }
        });
    }

    private void loadDataset() {
        TypeToken<List<DatasetVo>> typeToken = new TypeToken<>() {
        };
        HttpClient.getInstance().post("/dataset/list", "{}").callback(typeToken, list -> {
            tableView.getItems().clear();
            tableView.getItems().addAll(Optional.ofNullable(list).orElse(new ArrayList<>(0)));
        });
    }

    private void initDataSetItem() {
        // 监听选中行
        datasetItem.getSelectionModel().selectedIndexProperty().addListener((observable, oldValue, newValue) -> {
            boolean disable = newValue == null || newValue.intValue() == -1;
            editDatasetItem.setDisable(disable);
            deleteDatasetItem.setDisable(disable);
        });
    }

    private void loadDatasetItem(String datasetId) {
        TypeToken<List<DatasetItemVo>> typeToken = new TypeToken<>() {
        };
        DatasetItemVo qo = new DatasetItemVo();
        qo.setDatasetId(datasetId);
        HttpClient.getInstance().post("/datasetItem/list", qo).callback(typeToken, list -> {
            datasetItem.getItems().clear();
            datasetItem.getItems().addAll(Optional.ofNullable(list).orElse(new ArrayList<>(0)));
        });
    }

    public void addDataset(ActionEvent actionEvent) {
        log.info("addDataset:{}", actionEvent);
        addDataset();
    }

    private void addDataset() {
        try {
            DatasetEditController.showAddDialog(new DatasetVo(), datasetInfo ->
                    HttpClient.getInstance().post("/dataset/store", datasetInfo).callback(DatasetVo.class, datasetPo -> {
                        tableView.getItems().add(datasetPo);
                        tableView.getSelectionModel().select(datasetPo);
                    })
            );
        } catch (IOException e) {
            log.error("showDialog error", e);
        }
    }

    public void editDataset(ActionEvent actionEvent) {
        log.info("editDataset:{}", actionEvent);

        int selectedIndex = tableView.getSelectionModel().getSelectedIndex();
        editDataset(selectedIndex);
    }

    private void editDataset(int index) {
        DatasetVo selectedItem = tableView.getItems().get(index);
        try {
            DatasetEditController.showEditDialog(selectedItem, datasetInfo ->
                    HttpClient.getInstance().post("/dataset/store", datasetInfo).callback(DatasetVo.class, datasetPo ->
                            tableView.getItems().set(index, datasetPo))
            );
        } catch (IOException e) {
            log.error("showDialog error", e);
        }
    }

    public void deleteDataset(ActionEvent actionEvent) {
        log.info("deleteDataset:{}", actionEvent);
        DatasetVo datasetVo = tableView.getSelectionModel().getSelectedItem();
        if (datasetVo != null) {
            tableView.getItems().remove(datasetVo);
        }
    }

    public void addDatasetItem(ActionEvent event) {
        log.info("addDatasetItem:{}", event);
        String datasetId = tableView.getSelectionModel().getSelectedItem().getId();
        addDatasetItem(datasetId);
    }

    private void addDatasetItem(String datasetId) {
        try {
            DatasetItemVo datasetItemVo = new DatasetItemVo();
            datasetItemVo.setDatasetId(datasetId);
            DatasetItemEditController.showAddDialog(datasetItemVo, datasetItemInfo ->
                    HttpClient.getInstance().post("/datasetItem/store", datasetItemInfo).callback(DatasetItemVo.class, datasetItemPo -> {
                        datasetItem.getItems().add(datasetItemPo);
                        datasetItem.getSelectionModel().select(datasetItemPo);
                    })
            );
        } catch (IOException e) {
            log.error("showDialog error", e);
        }
    }


    public void editDatasetItem(ActionEvent event) {
        log.info("editDatasetItem:{}", event);
        int selectedIndex = datasetItem.getSelectionModel().getSelectedIndex();
        editDatasetItem(selectedIndex);
    }

    private void editDatasetItem(int index) {
        DatasetItemVo datasetItemVo = datasetItem.getItems().get(index);
        try {
            DatasetItemEditController.showEditDialog(datasetItemVo, datasetItemInfo ->
                    HttpClient.getInstance().post("/datasetItem/store", datasetItemInfo).callback(DatasetItemVo.class, datasetItemPo -> {
                        datasetItem.getItems().set(index, datasetItemPo);
                    })
            );
        } catch (IOException e) {
            log.error("showDialog error", e);
        }
    }

    public void deleteDatasetItem(ActionEvent event) {
        log.info("deleteDatasetItem:{}", event);
        DatasetItemVo datasetItemVo = datasetItem.getSelectionModel().getSelectedItem();
        if (datasetItemVo != null) {
            datasetItem.getItems().remove(datasetItemVo);
        }
    }

    public void onMouseClicked4dataset(MouseEvent mouseEvent) {
        if (mouseEvent.getClickCount() == 2) {
            log.info("onMouseClicked4dataset:{}", mouseEvent);
            TableViewUtil.traceTableRow(mouseEvent, tableRow -> {
                if (tableRow.isEmpty()) {
                    addDataset();
                } else {
                    editDataset(tableRow.getIndex());
                }
            });
        }
    }

    public void onMouseClicked4datasetItem(MouseEvent mouseEvent) {
        if (mouseEvent.getClickCount() == 2) {
            log.info("onMouseClicked4datasetItem:{}", mouseEvent);
            TableViewUtil.traceTableRow(mouseEvent, tableRow -> {
                if (tableRow.isEmpty()) {
                    DatasetVo selectedDataset = tableView.getSelectionModel().getSelectedItem();
                    if (selectedDataset != null && selectedDataset.getId() != null && !selectedDataset.getId().isBlank()) {
                        addDatasetItem(selectedDataset.getId());
                    }
                } else {
                    editDatasetItem(tableRow.getIndex());
                }
            });
        }
    }
}
